//
//  TryHoneNetFileUploadDownHelper.m
//  TryHoneBaseApp
//
//  Created by TryHone on 16/6/3.
//  Copyright © 2016年 TryHone. All rights reserved.
//

#import "JFNetFileUploadDownHelper.h"
#import "JFDataParserHelper.h"
#import "JFResultVo.h"
#import "JFFileModel.h"
#import "JFLogHelper.h"
#import "JFStringHelper.h"
#import "NSString+Hash.h"
#import "JFFileHelper.h"

#if __has_include(<AFNetworking/AFNetworking.h>)
#import <AFNetworking/AFNetworking.h>
#else
#import "AFNetworking.h"
#endif

@implementation JFNetFileUploadDownHelper{
    
    //请求对列
    NSMutableDictionary *_requestQueue;
    
    
}
+ (JFNetFileUploadDownHelper *)sharedManager
{
    static JFNetFileUploadDownHelper *sharedTryHoneNetFileUploadDownHelperManagerInstance = nil;
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{
        sharedTryHoneNetFileUploadDownHelperManagerInstance = [[self alloc] init];
    });
    return sharedTryHoneNetFileUploadDownHelperManagerInstance;
}
-(instancetype)init{
    self=[super init];
    if (self) {
        _requestQueue=[[NSMutableDictionary alloc] init];
    }
    return self;
}


#pragma mark--暴露出去的调用方法
-(void)requestWithFileRequestVo:(JFFileRequestVo*)requestVo progress:(JFFileUploadDownProgress)progress fail:(JFFileUploadDownFail)fail success:(JFFileUploadDownSuccess)success{


    NSString* jsonDataStr = [self parseParamData:requestVo];
    if (!jsonDataStr)
    {
        JFResultVo *resultVo = [[JFResultVo alloc] init];
        resultVo.errorInfo = @"请求数据转换失败,或参数错误";
        resultVo.errorNo=-2;
        fail(resultVo);
        return;
    }
    
    if (requestVo.isDebug) {
        [JFLogHelper stringSyncWriteLogToConsole:@"=========请求开始========="];
        [JFLogHelper stringSyncWriteLogToConsole:jsonDataStr];
    }
    //设置请求开始时间
    requestVo.beginTime=[[NSDate date]timeIntervalSince1970];
    //设置请求流水号
    requestVo.flowNo=[jsonDataStr md5String];
    

    if (requestVo.isUpload) { //上传文件
        [self upload:requestVo progress:^(double a, double b) {
            progress(a,b);
        } fail:^(JFResultVo *data) {
            fail(data);
        } success:^(JFResultVo *data) {
            success(data);
        }];
    }else{//下载文件
        
        [self downLoad:requestVo progress:^(double a, double b) {
            progress(a,b);
        } fail:^(JFResultVo *data) {
            fail(data);
        } success:^(JFResultVo *data) {
            success(data);
        }];
    }
    
    
    

}
-(void)cancelAllRequest{
  
    if (_requestQueue) {
        //取消所有的请求
        for (NSString*flowNo in _requestQueue.allKeys) {
            NSURLSessionDataTask* task=[_requestQueue objectForKey:flowNo];
            [task cancel];
        }
        [_requestQueue removeAllObjects];
    }
    
}


//取消一个请求
-(void)cancelOneRequest:(JFFileRequestVo*)requestVo{

        if (_requestQueue) {
             NSString * flowNo=[self getFlowNo:requestVo];
             if (![JFStringHelper isEmpty:flowNo]) {
        
               NSURLSessionDataTask* task=[_requestQueue objectForKey:flowNo];
               [task cancel];
               [_requestQueue removeObjectForKey:flowNo];
             }
        }

}

//暂停所有请求
-(void)suspendAllRequest{

    if (_requestQueue) {
        //取消所有的请求
        for (NSString*flowNo in _requestQueue.allKeys) {
            NSURLSessionDataTask* task=[_requestQueue objectForKey:flowNo];
            [task suspend];
        }
    }
}
//暂停一个请求
-(void)suspendOneRequest:(JFFileRequestVo*)requestVo{
    
     if (_requestQueue) {
    NSString * flowNo=[self getFlowNo:requestVo];
    if (![JFStringHelper isEmpty:flowNo]) {
        
        NSURLSessionDataTask* task=[_requestQueue objectForKey:flowNo];
        [task suspend];
    }
     }
}

//重启所有请求
-(void)reStartAllRequest{
    
    if (_requestQueue) {
        //取消所有的请求
        for (NSString*flowNo in _requestQueue.allKeys) {
            NSURLSessionDataTask* task=[_requestQueue objectForKey:flowNo];
            [task resume];
        }
    }

}
//重启一个请求
-(void)reStartOneRequest:(JFFileRequestVo*)requestVo{

    
    if (_requestQueue) {
        //取消所有的请求
        NSString * flowNo=[self getFlowNo:requestVo];
        if (![JFStringHelper isEmpty:flowNo]) {
            NSURLSessionDataTask* task=[_requestQueue objectForKey:flowNo];
            [task resume];
        }
    }
}


+(void)requestWithFileRequestVo:(JFFileRequestVo*)requestVo progress:(JFFileUploadDownProgress)progress fail:(JFFileUploadDownFail)fail success:(JFFileUploadDownSuccess)success{
    
    [[JFNetFileUploadDownHelper sharedManager] requestWithFileRequestVo:requestVo progress:^(double cur, double totle) {
        progress(cur,totle);
    } fail:^(JFResultVo *data) {
        fail(data);
    } success:^(JFResultVo *data) {
        success(data);
    }];

}
+(void)cancelAllRequest{
    [[JFNetFileUploadDownHelper sharedManager] cancelAllRequest];
}
//取消一个请求
+(void)cancelOneRequest:(JFFileRequestVo*)requestVo{
        [[JFNetFileUploadDownHelper sharedManager] cancelOneRequest:requestVo];
}

//暂停所有请求
+(void)suspendAllRequest{
   [[JFNetFileUploadDownHelper sharedManager] suspendAllRequest];
}
//暂停一个请求
+(void)suspendOneRequest:(JFFileRequestVo*)requestVo{
    [[JFNetFileUploadDownHelper sharedManager] suspendOneRequest:requestVo];
}

//重启所有请求
+(void)reStartAllRequest{
     [[JFNetFileUploadDownHelper sharedManager] reStartAllRequest];
}
//重启一个请求
+(void)reStartOneRequest:(JFFileRequestVo*)requestVo{
    [[JFNetFileUploadDownHelper sharedManager] reStartOneRequest:requestVo];
}



#pragma mark--内部实现方法
//上传文件
-(void)upload:(JFFileRequestVo*)data progress:(JFFileUploadDownProgress)progress fail:(JFFileUploadDownFail)fail success:(JFFileUploadDownSuccess)success{
    
    AFHTTPSessionManager *manager =[self getDefaultAFHTTPSessionManger];
    __weak __typeof(self) weakSelf=self;
    
   NSURLSessionDataTask* task = [manager POST:data.url parameters:data.reqParam headers:nil constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        NSMutableArray* dataArr=data.fileDataArr;
         for (JFFileModel* filedata in dataArr) {
             if (filedata) {
                 NSData * tempdata=[self getFileData:filedata];
                 NSString* tempfilename=[self getFileName:filedata];
                 NSString* tempfiletype=[self getFileType:filedata];
                 [formData appendPartWithFileData:tempdata name:filedata.filename fileName:tempfilename mimeType:tempfiletype];
                 
             }
         }
    } progress:^(NSProgress * _Nonnull uploadProgress) {
         progress(uploadProgress.completedUnitCount,uploadProgress.totalUnitCount);
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        JFResultVo * dict=nil;
              if(data.dataparserServiceName){
           
                  Class class = NSClassFromString(data.dataparserServiceName);
                  if([class respondsToSelector:@selector(dataParser:dataParserType: requestVo:)]){
                      dict = [class dataParser:responseObject dataParserType:data.dataparsertype requestVo:data];
                  }else if ([class respondsToSelector:@selector(dataParser:dataParserType:)]){
                      dict = [class dataParser:responseObject dataParserType:data.dataparsertype];
                  }else{
                      dict = [JFDataParserHelper dataParser:responseObject dataParserType:data.dataparsertype requestVo:data];
                  }
                  
              }else{
                  dict = [JFDataParserHelper dataParser:responseObject dataParserType:data.dataparsertype requestVo:data];
              }
              
              NSString * responce = [NSString stringWithFormat:@"--------请求响应begin---------\n接口:%@\n返回结果(%@)\n --------请求响应end-------",data.url,responseObject];
              [JFLogHelper stringSyncWriteLogToConsole:responce];
              if(!dict){
                  dict = [[JFResultVo alloc] init];
                  dict.errorNo = 0;
                  dict.noShowErrorInfo = @"文件上传成功，未解析到数据返回";
              }
              
              
              dispatch_async(dispatch_get_main_queue(), ^{
                  if (success) {
                       success(dict);
                  }
              });
              //把系统的内容清楚掉
              [weakSelf clearTask:data.flowNo];
              //debug的时候输出请求结束时间
              [weakSelf displayTime:data];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        JFResultVo *resultVo = [[JFResultVo alloc] init];
          resultVo.errorInfo = @"文件上传失败";
          resultVo.errorNo=-1;
          fail(resultVo);
          
          //把系统的内容清楚掉
          [weakSelf clearTask:data.flowNo];
    }];
      

    
//   NSURLSessionDataTask* task=[manager POST:data.url parameters:data.reqParam constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
//       
//       NSMutableArray* dataArr=data.fileDataArr;
//       for (JFFileModel* filedata in dataArr) {
//           if (filedata) {
//               NSData * tempdata=[self getFileData:filedata];
//               NSString* tempfilename=[self getFileName:filedata];
//               NSString* tempfiletype=[self getFileType:filedata];
//               [formData appendPartWithFileData:tempdata name:filedata.filename fileName:tempfilename mimeType:tempfiletype];
//               
//           }
//       }
//    } progress:^(NSProgress * _Nonnull uploadProgress) {
//        
//        progress(uploadProgress.completedUnitCount,uploadProgress.totalUnitCount);
//        
//    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
//        
//        JFResultVo * dict=nil;
//        if(data.dataparserServiceName){
//     
//            Class class = NSClassFromString(data.dataparserServiceName);
//            if([class respondsToSelector:@selector(dataParser:dataParserType: requestVo:)]){
//                dict = [class dataParser:responseObject dataParserType:data.dataparsertype requestVo:data];
//            }else if ([class respondsToSelector:@selector(dataParser:dataParserType:)]){
//                dict = [class dataParser:responseObject dataParserType:data.dataparsertype];
//            }else{
//                dict = [JFDataParserHelper dataParser:responseObject dataParserType:data.dataparsertype requestVo:data];
//            }
//            
//        }else{
//            dict = [JFDataParserHelper dataParser:responseObject dataParserType:data.dataparsertype requestVo:data];
//        }
//        
//        NSString * responce = [NSString stringWithFormat:@"--------请求响应begin---------\n接口:%@\n返回结果(%@)\n --------请求响应end-------",data.url,responseObject];
//        [JFLogHelper stringSyncWriteLogToConsole:responce];
//        if(!dict){
//            dict = [[JFResultVo alloc] init];
//            dict.errorNo = 0;
//            dict.noShowErrorInfo = @"文件上传成功，未解析到数据返回";
//        }
//        
//        
//        dispatch_async(dispatch_get_main_queue(), ^{
//            if (success) {
//                 success(dict);
//            }
//        });
//        //把系统的内容清楚掉
//        [weakSelf clearTask:data.flowNo];
//        //debug的时候输出请求结束时间
//        [weakSelf displayTime:data];
//        
//    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
//        JFResultVo *resultVo = [[JFResultVo alloc] init];
//        resultVo.errorInfo = @"文件上传失败";
//        resultVo.errorNo=-1;
//        fail(resultVo);
//        
//        //把系统的内容清楚掉
//        [weakSelf clearTask:data.flowNo];
//    }];
    
    [task resume];
    [_requestQueue  setObject:task forKey:data.flowNo];
    


}



//下载文件
-(void)downLoad:(JFFileRequestVo*)data progress:(JFFileUploadDownProgress)progress fail:(JFFileUploadDownFail)fail success:(JFFileUploadDownSuccess)success{
    
    
    AFHTTPSessionManager *manager =[self getDefaultAFHTTPSessionManger];
    __weak __typeof(self) weakSelf=self;
    
    if (data&&data.url&&data.url.length) {
         NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:data.url]];
       NSURLSessionDownloadTask* task= [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
             progress(downloadProgress.completedUnitCount,downloadProgress.totalUnitCount);
        } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
            
            
            if (![JFStringHelper isEmpty:data.savePath]) { //如果给了存储地址就使用给的地址
                return [NSURL URLWithString:data.savePath];
            }else{//如果没给就存在缓存文件夹下
                NSURL *downloadURL = [[NSFileManager defaultManager] URLForDirectory:NSCachesDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
                return [downloadURL URLByAppendingPathComponent:[response suggestedFilename]];
            }
            
            
        } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
        
            if (!error) {
                //下载成功后的回调
                JFResultVo *resultVo = [[JFResultVo alloc] init];
                resultVo.errorInfo = @"文件下载成功";
                resultVo.errorNo=0;
                NSMutableDictionary* dict=[[NSMutableDictionary alloc]init];
                [dict setObject:filePath forKey:@"filePath"];
                resultVo.results=dict;
                success(resultVo);
                
            }else{
                JFResultVo *resultVo = [[JFResultVo alloc] init];
                resultVo.errorInfo = @"文件下载失败";
                resultVo.errorNo=-1;
                success(resultVo);
            }
            //把系统的内容清楚掉
            [weakSelf clearTask:data.flowNo];
            //debug的时候输出请求结束时间
            [weakSelf displayTime:data];
            
        }];
        
        [task resume];
        
       [_requestQueue  setObject:task forKey:data.flowNo];
        
        
        
    }else{
    
        JFResultVo *resultVo = [[JFResultVo alloc] init];
        resultVo.errorInfo = @"文件下载失败";
        resultVo.errorNo=-1;
        fail(resultVo);
        
    }
}
-(NSString*)getFlowNo:(JFFileRequestVo*)vo{
  NSString* jsonDataStr = [self parseParamData:vo];
    if (![JFStringHelper isEmpty:jsonDataStr]) {
        return [jsonDataStr md5String];
    }else{
     return @"";
    }
}


//获取文件二进制数据
-(NSData*)getFileData:(JFFileModel*)data{
    if (data.filedata) {
        return data.filedata;
    }else{
        if (data.isFileUrl) {
            NSData* tempdata=[JFFileHelper readContentOfFile:data.fileurl];
            return tempdata;
        }else{
            return nil;//上传空数据会b调试会奔溃
        }
    }
    
   return nil;//上传空数据会b调试会奔溃
}
//获取文件名字
-(NSString*)getFileName:(JFFileModel*)data{
    
    if (data) {
        if ([JFStringHelper isEmpty:data.filename]) {
            return [JFStringHelper timestampString1000];
        }else{
            return data.filename;
        }
    }else{
        return [JFStringHelper timestampString1000];//获取时间戳作为文件名
    }
}
//获取文件类型 该函数使用于上传
-(NSString*)getFileType:(JFFileModel*)data{
    
    if (data) {
        
        
        if (data.filetype&&data.filetype.length>0) {//如果用户给了类型就使用用户的
            return data.filetype;
        }else{
        
            NSString* filetype=@"image/png";
            if (data.isFileUrl) {
                
                NSString* fileurl=data.fileurl;
                
                NSArray* data=[fileurl componentsSeparatedByString:@"."];
                
                if (fileurl&& data && data.count>1) {//url上可以获取后缀名的情况下
                    NSString* tempfiletype=data[1];
                    filetype=[self uploadFileType:tempfiletype];
                    
                }
                return  filetype;
                
            }
            return filetype;
        }
        
    }else{
      
        return @"";
    
    }
    
}




-(NSString*)uploadFileType:(NSString*)fileEx{
    NSString *uploadfiletype=@"image/png";
    if (![JFStringHelper isEmpty:fileEx]) {
       
        NSString* fileex=[fileEx lowercaseString];
        if ([@"jpeg" isEqualToString:fileex]){
            uploadfiletype=@"image/jpeg";
        }else if ([@"mp3" isEqualToString:fileex]){
            uploadfiletype=@"audio/mpeg3";
        }else{
            uploadfiletype=fileex;
            
        }
    }
    return uploadfiletype;
}


#pragma mark--公共方法
-(AFHTTPSessionManager*)getDefaultAFHTTPSessionManger{
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    return manager;
}

-(NSString *)parseParamData:(JFRequestVo *)requestVo
{
    NSMutableString *dataStr = [NSMutableString string];
    @try
    {
        [dataStr appendString:[NSString stringWithFormat:@"%@=%@",@"url",requestVo.url]];
        for (NSString  *key in requestVo.reqParam)
        {
            NSObject *obj = requestVo.reqParam[key];
            NSString *str;
            if ([obj isKindOfClass:[NSDictionary class]] || [obj isKindOfClass:[NSMutableDictionary class]])
            {
                NSData *data  = [NSJSONSerialization dataWithJSONObject:obj options:NSJSONWritingPrettyPrinted error:nil];
                str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
                str = [NSString stringWithFormat:@"%@=%@&",key,str];
            }
            else
            {
                str = [NSString stringWithFormat:@"%@=%@&",key,requestVo.reqParam[key]];
            }
            [dataStr  appendString:str];
        }
        
        
    }
    @catch (NSException *exception)
    {
      [JFLogHelper stringSyncWriteLogToConsole:[NSString stringWithFormat:@"=====请求数据解析异常%@",exception.description]];
        return nil;
    }
    return dataStr;
}


-(void)displayTime:(JFFileRequestVo*)data{
    if (data.isDebug) {
        NSTimeInterval endTime = [[NSDate date]timeIntervalSince1970];
        [JFLogHelper stringSyncWriteLogToConsole:[NSString stringWithFormat:@"花费时间(%fs)",(endTime - data.beginTime)]];
        [JFLogHelper stringSyncWriteLogToConsole:@"========请求结束======="];
    }
}

-(void)clearTask:(NSString*)flowNo{
    [_requestQueue removeObjectForKey:flowNo];
}


@end
